#include "resetdialog.h"
#include "ui_resetdialog.h"

ResetDialog::~ResetDialog(){
    delete ui;
}

ResetDialog::ResetDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::ResetDialog)
{
    ui->setupUi(this);

    // 输入框的内容验证
    connect(ui->user_edit, &QLineEdit::editingFinished, this, [this](){
        checkUserValid();
    });
    connect(ui->email_edit, &QLineEdit::editingFinished, this, [this](){
        checkEmailValid();
    });
    connect(ui->pwd_edit, &QLineEdit::editingFinished, this, [this](){
        checkPassValid();
    });
    connect(ui->varify_edit, &QLineEdit::editingFinished, this, [this](){
        checkVarifyValid();
    });

    // 连接reset相关信号和注册处理回调
    initHandlers();
    connect(HttpMgr::GetInstance().get(), &HttpMgr::sig_reset_mod_finish, this, &ResetDialog::slot_reset_mod_finish);
}

// 消息处理的声明
void ResetDialog::initHandlers(){
    // 重置密码获取验证码成功执行的处理函数
    _handlers.insert(ReqId::ID_GET_VARIFY_CODE, [this](QJsonObject jsonObj){
        int error = jsonObj["error"].toInt();
        if(error != ErrorCodes::SUCCESS){
            if(error == ErrorCodes::VarifyExpired) showTip(tr("验证码已过期"), false);
            else if(error == ErrorCodes::UserExist) showTip(tr("name或者email已经存在"), false);
            else showTip(tr("参数错误"), false);
            return;
        }

        auto email = jsonObj["email"].toString();
        showTip(tr("验证码已发送到邮箱，注意查收"), true);
        qDebug() << "email is" << email;
    });

    // 重置密码成功执行的处理函数
    _handlers.insert(ReqId::ID_RESET_PWD, [this](QJsonObject jsonObj){
        int error = jsonObj["error"].toInt();
        if(error != ErrorCodes::SUCCESS){
            if(error == ErrorCodes::VarifyExpired) showTip(tr("验证码已过期"), false);
            else if(error == ErrorCodes::UserExist) showTip(tr("name或者email已经存在"), false);
            else if(error == ErrorCodes::VarifyError) showTip(tr("验证码错误"), false);
            else if(error == ErrorCodes::EmailNotMatch) showTip(tr("user 和 email 不匹配"), false);
            else if(error == ErrorCodes::PasswdUpdateFail) showTip(tr("重置密码更新失败"), false);
            else showTip(tr("参数错误"), false);
            return;
        }
        showTip(tr("重置密码成功，点击返回登陆"), true);
        qDebug() << "user uuid is " << jsonObj["uuid"].toString();
        auto email = jsonObj["email"].toString();
        qDebug() << "email is " << email;
    });
}

// HttpMgr 请求处理完成返回执行的函数 ---> 调用 initHandlers 函数设置的回调处理函数
void ResetDialog::slot_reset_mod_finish(ReqId id, QString res, ErrorCodes err){
    if(err != ErrorCodes::SUCCESS){
        showTip(tr("网络错误"), false);
        return;
    }

    // 解析josn字符串，res需要转化为QByteArray
    QJsonDocument jsonDoc = QJsonDocument::fromJson(res.toUtf8());
    // json解析错误
    if(jsonDoc.isNull() == true){
        showTip(tr("json解析错误"), false);
        return;
    }
    // json解析错误
    if(jsonDoc.isObject() == false){
        showTip(tr("json解析错误"), false);
        return;
    }

    // 调用对应的回调函数
    _handlers[id](jsonDoc.object());
    return;
}

// 获取验证码按钮触发的槽函数
void ResetDialog::on_varify_btn_clicked(){
    qDebug() << "receive varify btn clicked";
    auto email = ui->email_edit->text();
    auto bcheck = checkEmailValid();
    if(bcheck == false) return;

    // 发送http请求获取验证码
    QJsonObject json_obj;
    json_obj["email"] = email;
    HttpMgr::GetInstance()->PostHttpReq(QUrl(gate_url_prefix + "/get_varifycode"), json_obj, ReqId::ID_GET_VARIFY_CODE, Modules::RESETMOD);
}
// 确认按钮触发的槽函数
void ResetDialog::on_confirm_btn_clicked(){
    // 先检验输入框中的内容是否合理
    bool valid = checkUserValid();
    if(valid == false) return;
    valid = checkEmailValid();
    if(valid == false) return;
    valid = checkPassValid();
    if(valid == false) return;
    valid = checkVarifyValid();
    if(valid == false) return ;

    // 发送Http重置用户密码请求
    QJsonObject json_obj;
    json_obj["user"] = ui->user_edit->text();
    json_obj["email"] = ui->email_edit->text();
    json_obj["pwd"] = xorString(ui->pwd_edit->text());
    json_obj["varifycode"] = ui->varify_edit->text();
    HttpMgr::GetInstance()->PostHttpReq(QUrl(gate_url_prefix + "/reset_pwd"), json_obj, ReqId::ID_RESET_PWD, Modules::RESETMOD);
}
// 返回按钮触发的槽函数
void ResetDialog::on_return_btn_clicked(){
    // 直接返回登陆界面
    qDebug() << "return_btn clicked";
    emit switchLogin();
}

// 提示函数(注意函数一旦发生改动的话，调用这个函数的地方也是要发生改动的，不发生改动的话，是可以加上默认参数的)
void ResetDialog::showTip(QString errstr, bool b_ok){
    if(b_ok == true)
        ui->err_tip->setProperty("state", "normal");
    else
        ui->err_tip->setProperty("state", "err");

    ui->err_tip->setText(errstr);
    repolish(ui->err_tip);
}

// 输入框的验证
bool ResetDialog::checkUserValid(){
    if("" == ui->user_edit->text()){
        AddTipErr(TipErr::TIP_USER_ERR, tr("用户名不能为空"));
        return false;
    }
    DelTipErr(TipErr::TIP_USER_ERR);
    return true;
}
bool ResetDialog::checkEmailValid(){
    // 验证邮箱的地址正则表达式
    auto email = ui->email_edit->text();
    if(email == "") return false;
    // 邮箱地址的正则表达式
    QRegularExpression regExp(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+)");
    bool match = regExp.match(email).hasMatch();
    if(match == false){
        // 提示邮箱不正确
        AddTipErr(TipErr::TIP_EMAIL_ERR, tr("邮箱地址不正确"));
        return false;
    }

    DelTipErr(TipErr::TIP_EMAIL_ERR);
    return true;
}
bool ResetDialog::checkPassValid(){
    auto pass = ui->pwd_edit->text();
    if(pass.length() < 4 || pass.length() > 30){
        // 提示长度不对
        AddTipErr(TipErr::TIP_PWD_ERR, tr("密码长度应为4~30"));
        return false;
    }

    // 创建一个正则表达式对象，按照上述密码要求
    // 这个正则表达式的解释：^[a-zA-Z0-9!@#$%^&*]{4,30}$ 密码长度至少4，可以是字母、数字和特定的特殊字符
    QRegularExpression regExp("^[a-zA-Z0-9!@#$%^&*]{4,30}$"); // 问gpt
    bool match = regExp.match(pass).hasMatch();
    if(match == false){
        // 提示字符非法
        AddTipErr(TipErr::TIP_PWD_ERR, tr("不能包含非法字符"));
        return false;
    }

    DelTipErr(TipErr::TIP_PWD_ERR);

    return true;
}
bool ResetDialog::checkVarifyValid(){
    if("" == ui->varify_edit->text()){
        AddTipErr(TipErr::TIP_VARIFY_ERR, tr("验证码不能为空"));
        return false;
    }

    DelTipErr(TipErr::TIP_VARIFY_ERR);
    return true;
}

// 添加和删除错误
void ResetDialog::AddTipErr(TipErr err, QString tip){
    _tip_errs[err] = tip;
    showTip(tip, false);
}
void ResetDialog::DelTipErr(TipErr err){
    // 移除前加上是否为空的判断，不然会引发奔溃；估计是先执行了DelTipErr
    if(_tip_errs.empty() == false)
        _tip_errs.remove(err);
    // 没有错误的话，ui->err_tip 错误提示框就不用显示内容了
    if(_tip_errs.empty() == true){
        ui->err_tip->clear();
        return;
    }
    showTip(_tip_errs.first(), false);
}


